string_match <- function(df1, df2, var1, var2) {
  ## Initialize container (matrix)
  names_intersect <- NULL
  
  ## Extract strings
  names_df1 <- df1[, var1]
  names_df2 <- df2[, var2]
  
  for (name in names_df1) {
    ## Exact matches
    p_exact_match <-
      names_df2[sapply(names_df2, split_match, name) == 0]
    
    if (length(p_exact_match) == 1) {
      print(paste0("Exact match: ", name))
      names_intersect <- rbind(names_intersect,
                                         c(name, p_exact_match, "exact match"))
      
    } else {
      ## First, find partial matches
      pmatch_names_df2 <-
        names_df2[sapply(names_df2, split_match, name) == 9]
      
      if (length(pmatch_names_df2) == 0) {
        ## No partial matches
        prompt_text <- paste0(
          "No match found for '",
          name,
          "'. Ctrl + F and choose row number. ",
          "For no match, hit ENTER: "
        )
        View(names_df2)
        accept <- as.numeric(readline(prompt = prompt_text))
        
        if (is.na(accept)) {
          print(paste0("No match for: ", name))
          names_intersect <-
            rbind(names_intersect,
                  c(name, NA, "no match"))
        } else {
          print(paste0("Accepted match for ", name, ": ", names_df2[accept]))
          names_intersect <-
            rbind(names_intersect,
                  c(name, names_df2[accept], "manual match"))
        }
      } else {
        ## Manual acceptance
        prompt_text <-
          paste0(
            "Partial matches found for '",
            name,
            "'. Ctrl + F and choose row number. ",
            "For no match, hit ENTER: "
          )
        View(pmatch_names_df2)
        accept <- as.numeric(readline(prompt = prompt_text))
        
        if (accept %in% seq_along(pmatch_names_df2)) {
          print(paste0("Accepted match for ", name, ": ", pmatch_names_df2[accept]))
          names_intersect <-
            rbind(names_intersect,
                  c(name, pmatch_names_df2[accept], "manual match"))
        } else {
          ## No partial matches
          prompt_text <- paste0(
            "No partial match found for '",
            name,
            "'. Ctrl + F and type",
            " in manually. For no match, hit ENTER:"
          )
          View(names_df2)
          accept <- as.numeric(readline(prompt = prompt_text))
          
          if (is.na(accept)) {
            print(paste0("No match for: ", name))
            names_intersect <-
              rbind(names_intersect,
                    c(name, NA, "no match"))
          } else {
            print(paste0("Accepted match for ", name, ": ", names_df2[accept]))
            names_intersect <-
              rbind(names_intersect,
                    c(name, names_df2[accept], "manual match"))
          }
        }
      }
    }
  }
  
  ## Post-process
  colnames(names_intersect) <-
    c("names_df1", "names_df2", "match_type")
  
  names_intersect <- as.data.frame(names_intersect)
  names_intersect$names_df1 <- as.character(names_intersect$names_df1)
  names_intersect$names_df2 <- as.character(names_intersect$names_df2)
  names_intersect$match_type <- as.character(names_intersect$match_type)
  
  ## Return value
  return(names_intersect)
}